package com.yugao.fintech.antelope.base.security.filter;

import com.yugao.fintech.antelope.base.model.constants.RequestCons;
import com.yugao.fintech.antelope.base.model.module.auth.LoginUser;
import com.yugao.fintech.antelope.base.model.module.auth.LoginUserHolder;
import com.yugao.fintech.antelope.base.model.module.tenant.TenantContextHolder;
import com.yugao.fintech.framework.assistant.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

@Slf4j
@Component
public class AuthFilter implements Filter, Ordered {

    public static List<String> excludePaths = new ArrayList<>();

    static {
        excludePaths.add("/v2/api-docs/**");
        excludePaths.add("/v3/api-docs/**");
        excludePaths.add("/login");
        excludePaths.add("/logout");
        excludePaths.add("/refresh");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        try {
            HttpServletRequest request = (HttpServletRequest) servletRequest;
            String requestURI = request.getRequestURI();
            if (StringUtils.matches(requestURI, excludePaths)) {
                chain.doFilter(request, response);
                return;
            }

            // 从请求头中拿到用户信息, 改用户信息由网关传递过来的
            LoginUser loginUser = LoginUser.decode(request.getHeader(RequestCons.Headers.LOGIN_USER));
            LoginUserHolder.set(loginUser);

            // 如果为空, 则表示尚未登录, 则设置主租户id
            if (Objects.isNull(loginUser) || Objects.isNull(loginUser.getUserId())
                    || loginUser.getTenant().getTenantId() == null || loginUser.getTenant().getTenantId() == -1) {
                TenantContextHolder.get().setTenantId(request.getHeader(RequestCons.Headers.TENANT_ID));
                TenantContextHolder.get().setMainTenantId(request.getHeader(RequestCons.Headers.TENANT_ID));
            } else {
                TenantContextHolder.get().setTenant(loginUser.getTenant());
            }

            chain.doFilter(request, response);
        } finally {
            LoginUserHolder.remove();
            TenantContextHolder.clear();
        }
    }

    @Override
    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE + 100;
    }
}
